/*
 * Created by 2006-1-29 23:20:55
 * $Id: BaseServlet.java 53 2006-06-28 15:52:26Z wjx $
 */
package com.someok.web.servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.someok.utils.StringUtil;

/**
 * 其它servlet的根类。
 *
 * <p>
 * <a href="BaseServlet.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author wjx
 * @version $Revision: 53 $ $Date: 2006-06-28 23:52:26 +0800 (星期三, 28 六月 2006) $
 */
public abstract class BaseServlet extends HttpServlet {

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		setCharacterEncoding(response);

		PrintWriter out = response.getWriter();

		out.println(outputPageBody(request, response));
	}

	/**
	 * 输出 servlet 页面.
	 * 之所以抽象出一个 abstract 方法，目的是控制编码设置（子类不需设置编码）。
	 * @param response
	 * @param request
	 * @return 整个页面
	 */
	abstract protected String outputPageBody(HttpServletRequest request, HttpServletResponse response);

	/**
	 * 设置 servlet 编码.
	 * 目的是将来如果需要修改编码，不会太麻烦。
	 * @param response
	 */
	protected void setCharacterEncoding(HttpServletResponse response) {
		response.setCharacterEncoding("UTF-8");
	}

	/**
	 * Get the absolute filepath of the file declared by the input
	 * <code>initParameter</code> parameter.
	 *
	 * @param initParameter
	 *            the name of the init-parameter declared into the web
	 *            application's web.xml configuration file. The initParameter
	 *            value must be a valid filename.
	 *
	 * @return the absolute filepath of the file name declared by the input
	 *         <code>initParameter</code> parameter.
	 */
	protected String getInitParameterFilePath(String initParameter) {
		String fileName = null;

		// cannot get the file name declared by the init-parameter;
		if (StringUtil.isNull(fileName = getInitParameter(initParameter))) {
			System.err
					.println("::init - the file name of the file declared by the init-parameter ["
							+ initParameter + "] is null or empty");
			return null;
		}

		// check if the file path of the file declared by the init-parameter
		// is relative to the web application directory;
		if (filePathIsRelative(fileName))
			return (getWebAppBasePath() + fileName);

		// file path is absolute; check for its existence;
		return (fileExists(fileName)) ? fileName : null;
	}

	/**
	 * PRIVATE METHODS here
	 */

	/**
	 * Check if the file declared by the input <code>fileName</code> parameter
	 * exists into the web application directory.
	 *
	 * @return true if the file exists, false otherwise.
	 */
	private boolean filePathIsRelative(String fileName) {
		String filePrefix = null;
		filePrefix = getWebAppBasePath();
		fileName = (filePrefix + "/" + fileName);

		return fileExists(fileName);
	}

	/**
	 * Check if the input file name exists.
	 *
	 * @param fileName
	 *            the full path name of the file to check
	 * @return true if the file exists, false otherwise.
	 */
	private boolean fileExists(String fileName) {
		return (new File(fileName).exists());
	}

	/**
	 * Return the web application absolute filepath.
	 *
	 * @return the web application absolute filepath.
	 */
	protected String getWebAppBasePath() {
		String result = (getServletContext().getRealPath("/"));
		// 部分web服务器在此处的解析有所不同
		if (result.endsWith("/")) {
			result = StringUtils.chop(result);
		}
		return result;
	}
}
